<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Object.keys()相关方法</title>
</head>
<body>
  <script>
    //es5引入了Object.keys方法，返回一个数组，成员是参数对象自身的(不含继承的)所有可遍历属性的键名。
    var obj = {foo: 'bar', baz: 42};
    Object.keys(obj); // ['foo', 'baz']
    /**
     * es2017引入了跟Object.keys配套使用的Object.values和Object.entries作为遍历一个对象的补充手段，
     * 供for...of循环使用。
     * Object.values方法返回一个数组，成员是参数对象自身的（不含继承的）所有可遍历（enumerable）属性的键值。
    */
    var val = Object.values(obj);
    console.log(val) // // ["bar", 42]
    // 返回数组的成员顺序，与本章的《属性的遍历》部分介绍的排列规则一致
    // Object.values会过滤属性名为Symbol值的属性
    Object.values({[Symbol()]: 123, foo: 'abc'}); // ['abc']
    Object.values('foo');
    // ['f', 'o', 'o']
    //上面代码中，字符串会先转成一个类似数组的对象。字符串的每个字符，就是该对象的一个属性。
    // 因此，Object.values返回每个属性的键值，就是各个字符组成的一个数组。
    /**
     * 如果参数不是对象，Object.values会先将其转为对象。由于数值和布尔值的包装对象，
     * 都不会为实例添加非继承的属性。所以，Object.values会返回空数组。
    */
    Object.values(42); // []
    Object.values(true); // []
  </script>
  <script>
    // Object,entries()方法返回一个数组，成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。
    var obj = { foo: 'baz', baz: 42 };
    var a = Object.entries(obj);
    console.log(a); // [ ["foo", "baz"], ["baz", 42] ]
    // 除了返回值不一样，该方法的行为与Object.values基本一致。
    // 如果原对象的属性名是一个Symbol值, 该属性会被忽略。
    Object.entries({[Symbol()]: 123, foo: 'abc'});
    // [ [ 'foo', 'abc' ] ]
    /**
     * 上面代码中，原对象有俩个属性，Object.entries只输出属性名非Symbol值的属性，
     * 将来可能会有Reflect.ownEntries()方法，返回对象自身的所有属性。
     * Object.entries的基本用途是遍历对象的属性。
    */
   var obj = { one: 1, two: 2};
   var arr = Object.entries(obj); // [ ["one", 1], ["two", 2] ]
   console.log('arr', arr)
   for (let [k,v] of arr) { // 这里的 [k,v]本质上是一种解构赋值
     console.log(
       `${JSON.stringify(k)}: ${JSON.stringify(v)}`
     )
   }
   // "one": 1
   // "two": 2
   // Object.entries方法的另一个用处是，将对象转为真正的Map解构。
   var obj = { foo: 'bar', baz: 42};
   var map = new Map(Object.entries(obj));
   console.log(map); // Map { foo: "bar", baz: 42 }  在浏览器中显示是Map(2) {"foo" => "bar", "baz" => 42}
  </script>
  <script>
    // 自己实现Object.entries方法，非常简单。
    // Generator函数的版本
    function* entries(obj) {
      for (let key of Object.keys(obj)) {
        yield [key, obj[key]]
      }
    }
    // 非Generator函数的版本
    function entries(obj) {
      let arr = []
      for (let key of Object.keys(obj)) {
        arr.push([key, obj[key]]);
      }
      return arr
    }
  </script>
</body>
</html>